package dao

import (
	"backend/app/dao/mysql"
	"backend/app/dao/redis"
	"backend/app/model"
	"backend/utils/function"
	"encoding/json"
	"fmt"
	"log"

	gredis "github.com/go-redis/redis/v8"
)

func QueryUserByID(userID int64) (*model.User, error) {
	return mysql.QueryUserByID(userID)
}

func QueryUserByUsername(username string) (*model.User, error) {
	return mysql.QueryUserByUsername(username)
}

func CheckUserIsExist(username string) (bool, error) {
	return mysql.CheckUserIsExistByUsername(username)
}

func SaveUser(user *model.User) error {
	isExist, err := mysql.CheckUserIsExistByUsername(user.UserName)
	if err != nil {
		return err
	}
	if isExist {
		return mysql.UpdateUser(user)
	} else {
		return mysql.InsertUser(user)
	}
}

func DeleteUser(userID int64) error {
	return mysql.DeleteUser(userID)
}

func DeleteUserInfo(userID int64) error {
	return mysql.DeleteUserInfo(userID)
}

func SaveUserRedisTokenData(udata *model.UserTokenData) error {
	rdb := redis.GetTokenRdb()
	userID := udata.UserID
	key := fmt.Sprintf("userTokenData:%d", userID)
	udataByte, err := json.Marshal(udata)
	if err != nil {
		return err
	}
	return redis.SetKey(rdb, key, string(udataByte))
}

func QueryUserRedisTokenData(userID int64) (*model.UserTokenData, error) {
	rdb := redis.GetTokenRdb()
	key := fmt.Sprintf("userTokenData:%d", userID)
	udataStr, err := redis.Query(rdb, key)
	if err != nil {
		return nil, err
	}
	var userData = new(model.UserTokenData)
	if err := json.Unmarshal([]byte(udataStr), userData); err != nil {
		return nil, err
	}
	return userData, nil
}

func SaveUserInfo(userInfo *model.UserInfo) error {
	rdb := redis.GetTokenRdb()
	rKey := "UserInfos:" + fmt.Sprintf("%d", userInfo.UserID)
	body, err := json.Marshal(userInfo)
	if err != nil {
		log.Println("-----ENJSON ERROR-----", err)
		return err
	}
	if err := redis.SetKey(rdb, rKey, string(body)); err != nil {
		log.Println("save userinfo in redis is failed,", err)
	}
	isExist, err := mysql.CheckUserInfoIsExist(userInfo.UserID)
	if err != nil {
		return err
	}
	if isExist {
		return mysql.UpdateUserInfo(userInfo)
	} else {
		return mysql.InsertUserInfo(userInfo)
	}
}

func QueryUserInfo(userID int64) (*model.UserInfo, error) {
	//
	rdb := redis.GetTokenRdb()
	rKey := "UserInfos:" + fmt.Sprintf("%d", userID)
	userInfoString, err := redis.Query(rdb, rKey)
	if err != nil {
		if err != gredis.Nil {
			return nil, err
		}
		//从mysql 查询
		userInfo, err := mysql.QueryUserInfo(userID)
		if err != nil {
			return nil, err
		}
		function.Go(func() {
			body, err := json.Marshal(userInfo)
			if err != nil {
				log.Println("-----ENJSON ERROR-----", err)
				return
			}
			if err := redis.SetKey(rdb, rKey, string(body)); err != nil {
				log.Println("set userinfo in redis is failed,", err)
			}
		})
		return userInfo, nil
	}
	var userInfo = new(model.UserInfo)
	if err := json.Unmarshal([]byte(userInfoString), userInfo); err != nil {
		return nil, err
	}
	return userInfo, nil
	// return mysql.QueryUserInfo(userID)
}

func QueryUserinfosByRoleName(rolename string) (*[]model.UserInfo, error) {
	return mysql.QueryUserinfosByRoleName(rolename)
}

func QueryAllUserByPage(page, pagesize int64) (*[]model.User, error) {
	return mysql.QueryAllUserByPage(page, pagesize)
}

func QueryAllUserCount() (int64, error) {
	return mysql.QueryAllUserCount()
}
